package cn.sccl.dirms.sms;

import cn.sccl.common.database.DataBase;
import cn.sccl.common.database.DataSet;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * 短信信息 消费者
 * Created by xf-cl on 2017/11/22.10:10
 */
@Service
public class ConsumerServiceImpl implements ConsumerService {
    private static Logger log = LoggerFactory.getLogger(ConsumerServiceImpl.class);
    // 短信keyid
    @Value("${sms.access_key_id}")
    private String accessKeyId;
    // 短信密钥
    @Value("${sms.access_key_secret}")
    private String accessKeySecret;

    //产品名称:云通信短信API产品,开发者无需替换
    @Value("${sms.product}")
    private String product;
    //产品域名,开发者无需替换
    @Value("${sms.domain}")
    private String domain;
    //暂不支持region化
    @Value("${sms.region}")
    private String region;

//    必填:短信签名-可在短信控制台中找到
    @Value("${sms.sign_name}")
    private String sign_name;
//    必填:短信模板-可在短信控制台中找到
    @Value("${sms.template_code}")
    private String template_code;
//    可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为{"name":"Tom", "code":"123"}
    @Value("${sms.template_params}")
    private String template_params;
    @Value("${sms.zabbix_params}")
    private String zabbix_params;


    //超时时间
    @Value("${sms.connecttimeout}")
    private String connecttimeout;
    //超时时间
    @Value("${sms.readtimeout}")
    private String readtimeout;

    @Autowired
    private DataBase dataBase;
    /**
     * 从mq队列接收信息  消费短信信息
     * @param jmxmessage
     */
    @Override
    public void comsumerSms(Message jmxmessage) throws Exception {
        ObjectMessage msg = (ObjectMessage)jmxmessage;
        try {
            ListOrderedMap map = (ListOrderedMap) msg.getObject();
            if(map != null && !map.isEmpty()){
                String id = MapUtils.getString(map,"alertid",null);
                String phone = MapUtils.getString(map,"sendto",null);
                String content = MapUtils.getString(map,"message",null);
                String unsql = " select * from alerts where alertid = ? ";
                DataSet d = dataBase.query(unsql,id);
                if(d.RowCount != 1){
                    log.debug("告警数据重复，不做发送！");
                    return;
                }
                // !=1 表示还未发送的和失败等待重新发送的
                if(d.getRow(0).getInt("status") != 1) {
                    log.debug("该告警数据存在且不是已发送的数据。");
                    if (!StringUtils.isEmpty(phone) && !StringUtils.isEmpty(content)) {
                        log.debug("开始构造短信的发送信息...");
                        //可自助调整超时时间
                        System.setProperty("sun.net.client.defaultConnectTimeout", connecttimeout);
                        System.setProperty("sun.net.client.defaultReadTimeout", readtimeout);

                        //初始化acsClient,暂不支持region化
                        IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
                        DefaultProfile.addEndpoint(region, region, product, domain);
                        IAcsClient acsClient = new DefaultAcsClient(profile);

                        //组装请求对象-具体描述见控制台-文档部分内容
                        SendSmsRequest request = new SendSmsRequest();
                        //必填:待发送手机号
                        request.setPhoneNumbers(phone);
                        //必填:短信签名-可在短信控制台中找到
                        request.setSignName(sign_name);
                        //必填:短信模板-可在短信控制台中找到
                        request.setTemplateCode(template_code);
                        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
                        String[] params = template_params.split(",");
                        String[] cnparams = zabbix_params.split(",");
                        //数据库查出的按照zabbix告警模板生成的实际数据数据
                        String[] lines = content.split("\\n|\\n\\r|\\r");
                        String obj = "{";
                        for (int i=0;i<params.length;i++) {
                            String key = params[i];
                            String cnKey = cnparams[i];
                            String value = "";
                            for(String line :lines){
                                if(line != null && !line.isEmpty() && line.indexOf("：") > -1) {
                                    String[] kv = line.split("：");
                                    String k = kv[0];
                                    String v = kv[1];
                                    if(cnKey.equalsIgnoreCase(k)){
                                        //告警信息格式化
                                        if(key.equalsIgnoreCase("level")){
                                            if("not classified".equalsIgnoreCase(v)){
                                                value = "未分类";
                                            }else if("information".equalsIgnoreCase(v)){
                                                value = "信息";
                                            }else if("warning".equalsIgnoreCase(v)){
                                                value = "警告";
                                            }else if("average".equalsIgnoreCase(v)){
                                                value = "一般严重";
                                            }else if("high".equalsIgnoreCase(v)){
                                                value = "严重";
                                            }else if("disaster".equalsIgnoreCase(v)){
                                                value = "灾难";
                                            }else{
                                                value = "";
                                            }
                                        }else {
                                            value = v;
                                        }
                                        break;
                                    }
                                }
                            }
                            if(value != null && !value.isEmpty()){
                                obj += "\"" + key + "\":" + "\"" + value + "\",";
                            }
                        }
                        if (obj.length() > 1) {
                            obj = obj.substring(0, obj.length() - 1);
                        }
                        obj += "}";
                        log.debug("构造短信的发送信息参数为:"+obj);
                        request.setTemplateParam(obj);

                        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
                        //request.setSmsUpExtendCode("90997");

                        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
                        request.setOutId(id);
                        log.debug("开始发送短信：告警id:"+id);
                        //hint 此处可能会抛出异常，注意catch
                        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
                        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                            log.debug("短信发送成功！开始修改告警表状态字段");
                            //请求成功
                            String sql = " UPDATE alerts SET status = 1 WHERE alertid = ? ";
                            int i = dataBase.executeUpdate(sql,id);
                            if(i > 0 ) {
                                log.debug("短信发送成功！修改告警表状态字段成功");
                            }else {
                                log.error("短信发送成功！修改告警表状态字段失败:");
                            }
                        }else{
                            log.debug("短信发送失败！失败信息："+sendSmsResponse.getMessage());
                        }
                    }else{
                        log.debug("要发生的手机号和内容不能为空！");
                    }
                }else{
                    log.debug("该告警数据不存在或是已发送的数据。");
                }
            }else{
                log.debug("从activemq队列中接收到的消息不存在。");
            }
        } catch (Exception e) {
            log.error("异常："+e);
            throw new Exception("为事务抛出异常");
        }
    }
}
